<template>
  <div
    class="warp"
    id="ProgressBar"
  >
    <div
      class="bar"
      ref="bar"
    />
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
interface LoadingBarContext {
  zIndex?: string | null
  bgColor?: string | null
  height?: number | string
}
const DEF_OPTIONS = { zIndex: '999999', bgColor: '#2962ff', height: 2 }
const bar = ref<HTMLElement>()
const sped = ref<number>(1)
const timer = ref<number>(0)
// 初始参数
const stateOpyions = ref<LoadingBarContext>({
  ...DEF_OPTIONS
})
// 初始化lodding加载
const showProgressBar = (options: LoadingBarContext): void => {
  stateOpyions.value = { ...options }
  sped.value = 1
  if (timer.value !== 0) window.cancelAnimationFrame(timer.value)
  timer.value = window.requestAnimationFrame(incmreent())
}
const incmreent = (): any => {
  const { zIndex = '999999', bgColor = '#2962ff', height = 2 } = stateOpyions.value
  const dom = bar.value as any
  dom.style.display = 'black'
  dom.style.backgroundColor = bgColor
  dom.style.zIndex = zIndex
  dom.style.height = height + 'px'
  return function fn () {
    sped.value += 1
    if (sped.value <= 90) {
      dom.style.width = sped.value + '%'
      timer.value = window.requestAnimationFrame(fn)
    } else {
      sped.value = 1
      window.cancelAnimationFrame(timer.value)
    }
  }
}
const closeProgressBar = (): void => {
  timer.value = window.requestAnimationFrame(closeProgress())
  stateOpyions.value = { ...DEF_OPTIONS }
}
const closeProgress = (): any => {
  return function () {
    const dom = bar.value as any
    sped.value = 100
    dom.style.width = sped.value + '%'
    setTimeout(() => {
      dom.style.display = 'none'
    }, 200)
    window.cancelAnimationFrame(timer.value)
  }
}
defineExpose({
  showProgressBar,
  closeProgressBar
})
</script>
<style scoped>
.warp {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}
.warp .bar {
  width: 0;
  height: 2px;
}
</style>
